package com.linkgie.galaxyframework.crypto;

import com.linkgie.galaxyframework.utils.Base58Encoding;
import com.linkgie.galaxyframework.utils.BinaryUtils;

public class DoubleHashAddressGenerator implements BinaryAddressGenerator {

	public static final String ALGORITHM_PREFIX = "HASH";

	private final String algorithm;
	
	private byte[] seedBytes;
	
	private HashFunc contentHasher;

	private HashFunc addressHasher;

	@Override
	public String getAlogrithm() {
		return algorithm;
	}

	public DoubleHashAddressGenerator(long seed, HashService contentHasher, HashService addressHasher) {
		this.seedBytes = BinaryUtils.toBytes(seed);
		this.contentHasher = contentHasher;
		this.addressHasher = addressHasher;

		this.algorithm = HashAddressAlgorithms.createName(ALGORITHM_PREFIX, contentHasher.getAlgorithm(), addressHasher.getAlgorithm(), seed);
	}

	@Override
	public CryptoAddress generate(byte[] input) {
		if (input == null || input.length == 0) {
			throw new IllegalArgumentException("The input is empty!");
		}
		byte[] content = BinaryUtils.concat(seedBytes, input);
		byte[] addressBytes = addressHasher.hashInRaw(contentHasher.hashInRaw(content));
		return new CryptoAddressEntry(algorithm, addressBytes);
	}

	private static class CryptoAddressEntry implements CryptoAddress {

		private String algorithm;

		private byte[] addressBytes;

		public CryptoAddressEntry(String algorithm, byte[] addressBytes) {
			this.algorithm= algorithm;
			this.addressBytes = addressBytes;
		}

		@Override
		public String getAlgorithm() {
			return algorithm;
		}

		@Override
		public byte[] toBytes() {
			return addressBytes.clone();
		}

		@Override
		public String toBase58() {
			return Base58Encoding.encode(addressBytes);
		}

	}

}
